#include "programlauncher.h"
#include "mainwindow.h"
#include "configurationview.h"
#include "informationview.h"
#include "recognitionview.h"
#include "maincontroller.h"
#include "camerathread.h"
#include "informationthread.h"
#include "controlview.h"
#include "dbimagemanager.h"

using namespace views;
using namespace models;
using namespace controllers;

ProgramLauncher::ProgramLauncher()
{
    _started = false;
}

void ProgramLauncher::startApplication(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // Show splashcreen
    // ...

    // Create the main view and the different application state views:
    // (Configuration, Information, Recognition)

    // Main window
    MainWindow mainWindow;

    // Configuration view
    ConfigurationView configurationView;

    // Information view
    InformationView informationView;

    // Recognition view
    RecognitionView recognitionView;

    // Add the views to the main window
    mainWindow.setView(&configurationView,  CONFIGURATION_VIEW);
    mainWindow.setView(&informationView,    INFORMATION_VIEW);
    mainWindow.setView(&recognitionView,    RECOGNITION_VIEW);
    mainWindow.showViews();

    // Create the main controller
    MainController mainController;

    // Create the thread objects for camera and information
    CameraThread cameraThread;
    cameraThread.setView(&recognitionView);

    // Text spashscreen ...

    // Load DB images, compute and save their histograms
    DBImageManager dbImg;dbImg.getDBImages();
    cameraThread.computeDBImageHistograms(dbImg.getDBImages());

    InformationThread informationThread;
    informationThread.setView(&informationView);

    // Set thread objects in the main controller
    mainController.setCameraThread(&cameraThread);
    mainController.setInformationThread(&informationThread);

    // Set the main controller in the main window
    mainWindow.setMainController(&mainController);

    // Setup the necessary listeners between objects
    QObject::connect(&configurationView, SIGNAL(startVision()), &mainWindow, SLOT(startVision()));
    QObject::connect(&configurationView, SIGNAL(stopVision()), &mainWindow, SLOT(stopVision()));
    QObject::connect((ControlView*)mainWindow.getView(CONTROL_VIEW), SIGNAL(takeReference()), &mainController, SLOT(takeReferenceImage()));
    QObject::connect((ControlView*)mainWindow.getView(CONTROL_VIEW), SIGNAL(recordVideo()), &mainController, SLOT(recordVideo()));
    QObject::connect((ControlView*)mainWindow.getView(CONTROL_VIEW), SIGNAL(takeSnapshot()), &mainController, SLOT(takeSnapshotImage()));
    QObject::connect((ControlView*)mainWindow.getView(CONTROL_VIEW), SIGNAL(recognizeObject()), &mainController, SLOT(recognizeObject()));

    // Hide splashcreen
    // ...

    // Show Configuration view
    mainWindow.showView(CONFIGURATION_VIEW);

    // Show Main window
    mainWindow.show();

    a.exec();
}
